package com.pkk.cloud.support.oauth2.config.configuration;

import com.pkk.cloud.support.oauth2.config.entrypoint.Oauth2ExceptionEntryPoint;
import com.pkk.cloud.support.oauth2.config.handle.Oauth2AccessDeniedHandler;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.oauth2.config.annotation.web.configuration.EnableResourceServer;
import org.springframework.security.oauth2.config.annotation.web.configuration.ResourceServerConfigurerAdapter;
import org.springframework.security.oauth2.config.annotation.web.configurers.ResourceServerSecurityConfigurer;
import org.springframework.security.web.authentication.logout.LogoutHandler;
import org.springframework.security.web.authentication.logout.LogoutSuccessHandler;

/**
 * @Description: 配置资源请求配置, 拦截请求进行处理
 * @return:
 * @Author: peikunkun
 * @Date: 2020/3/19 0019 下午 2:31
 */
@Configuration
//此注解优先于普通的路径之前,在/oauth/tokan之后的路径归他管
@EnableResourceServer
public class ResourceServerConfiguration extends ResourceServerConfigurerAdapter {

  @Autowired
  private LogoutHandler logoutHandler;

  @Autowired
  private LogoutSuccessHandler logoutSuccessHandler;

  /**
   * ********************************************特殊说明:
   * 1. 当我们在做oauth2的时候，当把两个类同时放在项目的时候，都声明了对http url的不同处理，
   *    但是就是ResourceServerConfigurerAdapter会把的http配置信息完全被覆盖掉，最后形成了，
   *    所有的请求只会在ResourceServerConfigurerAdapter的fitler chain中处理
   *   【正常情况下WebSecurityConfigurerAdapter的拦截优先于ResourceServerConfigurerAdapter】【优先级高的http配置是可以覆盖优先级低的配置的】
   * 2.ResourceServerConfigurerAdapter是默认情况下spring security oauth2的http配置
   * 3.WebSecurityConfigurerAdapter是默认情况下spring security的http配置
   *
   */

  /**
   * @Description: 配置http请求的拦截操作
   * <p>
   *
   * <p>------------------------------
   * <p>此处是oauth-center认证中心的资源请求拦截配置
   * <p>------------------------------
   * @Param: http
   * @return: void
   * @Author: peikunkun
   * @Date: 2020/3/19 0019 下午 2:32
   */
  @Override
  public void configure(HttpSecurity http) throws Exception {
    //@formatter:off
    // 禁止跨域请求
    http.csrf().disable()
        // 定义权限配置
        .authorizeRequests()
        /*js等操作给全部权限*/
        //.antMatchers("/**/test.*", "/**/*.css","/**/*.js","/**/images/*").permitAll()
        //【/v2/api-docs】无需访问权限
        .antMatchers("/v2/api-docs").permitAll()
        // 其余所有请求全部需要鉴权认证
        .anyRequest().authenticated()
        .and()
          // login页面自定义配置都可以访问
          .formLogin()// 使用Java配置默认值设置了基于表单的验证。使用POST提交到”/login”时，需要用”username”和”password”进行验证
          .loginPage("/login")                                            // 注明了登陆页面，意味着用GET访问”/login”时，显示登陆页面
          .permitAll()
        //退出登录
        .and()
            //登出的url
            .logout().logoutUrl("/oauth/logout")
        //退出登录的处理
        .addLogoutHandler(logoutHandler)
        //退出登录成功的处理
        .logoutSuccessHandler(logoutSuccessHandler).permitAll()
        //删除session
        .deleteCookies("JSESSIONID", "FP-UID")
        //使session会话失效
        .invalidateHttpSession(true);
    //@formatter:on
  }

  /**
   * @Description: 配置资源的一些相应处理的响应结果
   * @Param: resources
   * @return: void
   * @Author: peikunkun
   * @Date: 2020/3/19 0019 下午 2:54
   */
  @Override
  public void configure(ResourceServerSecurityConfigurer resources) throws Exception {
    //资源响应的信息配置
    resources.authenticationEntryPoint(new Oauth2ExceptionEntryPoint())
        //拒绝访问的处理
        .accessDeniedHandler(new Oauth2AccessDeniedHandler());
  }
}
